package com.hougong.im.service;

import com.hougong.im.annotation.IMAction;
import com.hougong.im.body.httpresponse.MyFriendListVo;
import com.hougong.im.body.notice.OnlineStatusNotice;
import com.hougong.im.body.request.LoginRequest;
import com.hougong.im.body.response.LoginResponse;
import com.hougong.im.common.GlobalCode;
import com.hougong.im.entity.ChatUser;
import com.hougong.im.mapper.ChatUserMapper;
import com.hougong.im.mapper.FriendMapper;
import com.hougong.im.pool.ConnPool;
import com.hougong.im.transport.BaseFrame;
import com.hougong.im.transport.HeartbeatHandler;
import com.hougong.im.utils.JwtUtils;
import com.hougong.im.utils.SendUtils;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("accountService")
public class AccountService {
    private static final Logger LOGGER=LoggerFactory.getLogger(AccountService.class);

    @Autowired
    private ChatUserMapper chatUserMapper;

    @Autowired
    private FriendMapper friendMapper;

    /**
     *   客户端发送 6C 00 00 00 0A 00 00 00 01 01 00 00 02 00 01 09
     *   服务器接受到进入 后发送消息给给客户端  6C 00 00 00 0C 00 00 00 00 01 02 00 03 01 02 03 04 08 验证Ok
     * @param baseFrame
     * @param channel
     */
    @IMAction(0x0003)
    public void Login(BaseFrame baseFrame, Channel channel){
        //解码到  body登录 协议中 转化成pojo  判断账号密码等一些校验 后保存当前连接
        // 启动心跳检测  发送好友列表群组列表   发送未读消息 更新好友中的好友列表状态 比较多牵动的东西很多
        byte[] body = baseFrame.getBody();
        LoginRequest loginRequest=new LoginRequest();
        loginRequest.fillBodyPojo(Unpooled.wrappedBuffer(body));
        ChatUser chatUserResult = chatUserMapper.selectByUserNamePwd(loginRequest.getUserName(),loginRequest.getPassword());
        LOGGER.info("loginRequest"+loginRequest);
        if(chatUserResult!=null){
            LOGGER.info("登录成功"+chatUserResult);
            ConnPool.addTcp(chatUserResult.getId(),channel);
            HeartbeatHandler heartbeatHandler = (HeartbeatHandler) channel.pipeline().get("HeartbeatHandler");
            heartbeatHandler.setUid(chatUserResult.getId());
            LoginResponse loginResponse=new LoginResponse();
            loginResponse.setFlag(LoginResponse.Success_Flag);
            loginResponse.setTips(LoginResponse.Success_Tips);
            loginResponse.setTipsLen((short) LoginResponse.Success_Tips.getBytes().length);
            String token = JwtUtils.generateToken(chatUserResult.getId(), chatUserResult.getPhone());
            loginResponse.setToken(token);
            loginResponse.setTokenLen(token.getBytes().length);
            loginResponse.setUid(chatUserResult.getId());
            SendUtils.sendResponse(channel,GlobalCode.Login_Response.getBizCode(),loginResponse);
            //通知好友
            notifyMyFriend(chatUserResult.getId());
        }else{
            //登录失败
            LoginResponse loginResponse=new LoginResponse();
            loginResponse.setFlag(LoginResponse.Error_Flag);
            loginResponse.setTips(LoginResponse.Error_Tips);
            loginResponse.setTipsLen((short) LoginResponse.Error_Tips.getBytes().length);
            loginResponse.setToken(LoginResponse.Error_Token);
            loginResponse.setTokenLen(LoginResponse.Error_Token.getBytes().length);
            SendUtils.sendResponse(channel,GlobalCode.Login_Response.getBizCode(),loginResponse);
        }
    }

    /**
     * 给好友的通知信息
     * @param currentUid
     */
    public void  notifyMyFriend(Long currentUid){
        //上线了
        List<MyFriendListVo> myFriends = friendMapper.findMyFriends(currentUid);
        final OnlineStatusNotice onlineStatusNotice=new OnlineStatusNotice();
        onlineStatusNotice.setFid(currentUid);
        onlineStatusNotice.setStatus((byte) 1);
        for(MyFriendListVo friendListVo:myFriends){
            Channel query = ConnPool.queryTCP(friendListVo.getUid());
            if(query!=null){
                SendUtils.sendNotice(query,GlobalCode.Friend_OnLine_Status_Notice.getBizCode(),onlineStatusNotice);
            }
        }
    }
}
